package com.antonytrupe.fatcontroller.pc;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.UUID;

import com.antonytrupe.fatcontroller.Engine;
import com.antonytrupe.fatcontroller.Search;
import com.antonytrupe.fatcontroller.pc.ui.EngineListPanel;

public class PCSearch implements Search {

	@Override
	public void enableRefresh(boolean enabled) {
		// TODO delegate toggling the refresh button
		// this.refreshButton.setEnabled(enabled);

	}
	
	 
	public void deviceDiscovered(RemoteDevice remoteDevice,
			DeviceClass deviceClass) {
		try {
			System.out.println("deviceDiscovered:"
					+ remoteDevice.getFriendlyName(true));
		} catch (IOException e) {
			e.printStackTrace();
		}
		// Keep track of discovered remote devices
		remoteDevices.put(remoteDevice.getBluetoothAddress(), remoteDevice);

		// TODO
		// initiateServiceSearch(remoteDevice);
	}
	
	 
	public void displayEngines( ) {
		mainFrame.getContentPane().removeAll();
		mainFrame.getContentPane().add(
				new EngineListPanel(search.getEngines(), this));
		mainFrame.getContentPane().validate();
		mainFrame.getContentPane().repaint();
	}

	private void initiateServiceSearch(RemoteDevice rd) {
		// Initiate the service search on the remote device
		try {
			System.out.println("Service Search started for "
					+ rd.getFriendlyName(false));
			int transID = discoveryAgent.searchServices(null, uuids, rd, this);
			// Display progress message
			System.out.println("Service Search " + transID + " in Progress");
			synchronized (serviceSearchSemaphore) {
				serviceSearchSemaphore.wait();
			}
		} catch (InterruptedException ie) {
			// Ignore
		} catch (BluetoothStateException bse) {
			// ...
			System.out.println("Service Search Failed");
			return;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// local Bluetooth Manager
	private static LocalDevice localDevice;
	static {
		try {
			localDevice = LocalDevice.getLocalDevice();
			localDevice.setDiscoverable(DiscoveryAgent.GIAC);
			discoveryAgent = localDevice.getDiscoveryAgent();
		} catch (BluetoothStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	// discovery agent
	private static DiscoveryAgent discoveryAgent;
	private HashMap<String, RemoteDevice> remoteDevices = new HashMap<String, RemoteDevice>();
	private Object serviceSearchSemaphore;
	// Bluetooth service UUID
	private static final String myServiceUUID = "2d26618601fb47c28d9f10b8ec891363";
	private UUID MYSERVICEUUID_UUID = new UUID(myServiceUUID, false);
	private UUID[] uuids = { MYSERVICEUUID_UUID };
	private boolean inquiryRunning;

	private ArrayList<Engine> engines = new ArrayList<Engine>();

	@Override
	public ArrayList<Engine> getEngines() {
		// TODO remove
		engines.add(new Engine("Thomas"));
		engines.add(new Engine("Percy"));
		return engines;
	}

	@Override
	public void initiateEngineSearch() {
		enableRefresh(false);

		RemoteDevice[] cachedDevices = discoveryAgent
				.retrieveDevices(DiscoveryAgent.CACHED);
		if (cachedDevices != null) {
			for (RemoteDevice rd : cachedDevices) {
				remoteDevices.put(rd.getBluetoothAddress(), rd);
			}
		}

		RemoteDevice[] preknownDevices = discoveryAgent
				.retrieveDevices(DiscoveryAgent.PREKNOWN);
		if (preknownDevices != null) {
			for (RemoteDevice rd : preknownDevices) {
				remoteDevices.put(rd.getBluetoothAddress(), rd);
			}
		}
		if (!inquiryRunning) {
			try {
				inquiryRunning = discoveryAgent.startInquiry(
						DiscoveryAgent.GIAC, this);
			} catch (BluetoothStateException e) {
				e.printStackTrace();
			}
		}
	}

}
